﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AwesomeSlider.Extensions;
using AwesomeSlider.Models;
using AwesomeSlider.Services;
using Orchard;
using Orchard.ContentManagement;
using Orchard.Data;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Settings;
using Orchard.UI.Admin;
using Orchard.UI.Navigation;
using Orchard.UI.Notify;


namespace AwesomeSlider.Controllers
{
    [ValidateInput(false), Admin]
    public class SlidersAdminController : Controller, IUpdateModel
    {
        public Localizer T { get; set; }
        private readonly IOrchardServices _services;
        private readonly IContentManager _contentManager;
        private readonly ITransactionManager _transactionManager;
        private readonly ISiteService _siteService;
        private readonly ISliderService _sliderService;
        private readonly IMediaExtendedService _mediaService;
        private readonly ISliderItemService _sliderItemService;
        dynamic Shape { get; set; }


        public SlidersAdminController(IOrchardServices services, IShapeFactory shapeFactory,
            IContentManager contentManager, ITransactionManager transactionManager, ISiteService siteService,
            ISliderService sliderService, ISliderItemService sliderItemService, IMediaExtendedService mediaService)
        {
            _services = services;
            Shape = shapeFactory;

            _contentManager = contentManager;
            _transactionManager = transactionManager;
            _siteService = siteService;
            _sliderService = sliderService;
            _sliderItemService = sliderItemService;
            _mediaService = mediaService;
        }

        public ActionResult Summary()
        {
            var albums = _sliderService.Get().Select(a =>
                _services.New.Sliders_SummaryAdmin(
                    ContentItem: a.ContentItem));

            var list = Shape.List();
            list.AddRange(albums);

            dynamic viewModel = Shape.ViewModel().ContentItems(list);

            // Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
            return View((object)viewModel);
        }

        public ActionResult Create()
        {
            if (!_services.Authorizer.Authorize(Permissions.ManageSliders, T("Not allowed to create slider")))
                return new HttpUnauthorizedResult();

            IContent slider = _sliderService.Create();

            if (slider == null)
                return HttpNotFound();
            //setDefault
            var parts = slider.ContentItem.Parts.OfType<ISliderPart>();
            foreach (var contentPart in parts)
            {
                contentPart.SetDefault();
            }
            dynamic model = _services.ContentManager.BuildEditor(slider);
            // Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
            return View((object)model);
        }

        [HttpPost, ActionName("Create")]
        public ActionResult CreatePOST()
        {
            if (!_services.Authorizer.Authorize(Permissions.ManageSliders, T("Couldn't create slider")))
                return new HttpUnauthorizedResult();

            var slider = _sliderService.Create();

            _contentManager.Create(slider, VersionOptions.Draft);
            dynamic model = _contentManager.UpdateEditor(slider, this);

            if (!ModelState.IsValid)
            {
                _transactionManager.Cancel();
                // Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
                return View((object)model);
            }

            _contentManager.Publish(slider.ContentItem);

            return Redirect(Url.SliderSummary());
        }

        public ActionResult Edit(int sliderId)
        {
            if (!_services.Authorizer.Authorize(Permissions.ManageSliders, T("Not allowed to edit slider")))
                return new HttpUnauthorizedResult();

            var sliderPart = _sliderService.Get(sliderId, VersionOptions.Latest);
            if (sliderPart == null)
                return HttpNotFound();

            dynamic model = _services.ContentManager.BuildEditor(sliderPart);
            // Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
            return View((object)model);
        }

        [HttpPost, ActionName("Edit")]
        public ActionResult EditPOST(int sliderId)
        {
            if (!_services.Authorizer.Authorize(Permissions.ManageSliders, T("Couldn't edit sliders")))
                return new HttpUnauthorizedResult();

            var slider = _sliderService.Get(sliderId, VersionOptions.DraftRequired);
            if (slider == null)
                return HttpNotFound();

            dynamic model = _services.ContentManager.UpdateEditor(slider, this);
            if (!ModelState.IsValid)
            {
                _services.TransactionManager.Cancel();
                // Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
                return View((object)model);
            }

            _contentManager.Publish(slider);

            _services.Notifier.Information(T("Slider information updated"));

            return Redirect(Url.SliderSummary());
        }


        public ActionResult RemoveSlider(int sliderId, bool deleteFolder)
        {
            if (!_services.Authorizer.Authorize(Permissions.ManageSliders, T("Couldn't delete slider")))
                return new HttpUnauthorizedResult();

            var slider = _sliderService.Get(sliderId, VersionOptions.Latest);

            if (slider == null)
                return HttpNotFound();

            _sliderService.Delete(slider);

            var sliderPart = slider.As<SliderPart>();

            if (deleteFolder)
            {
                try
                {
                    _mediaService.DeleteFolder(sliderPart.Name);
                    _services.Notifier.Information(T(string.Format("Folder {0} was successfully deleted.", sliderPart.Name)));
                }
                catch (Exception)
                {
                    _services.Notifier.Error(T(string.Format("Cannot delete folder {0}. Please remove it manually.", sliderPart.Name)));
                }

            }

            _services.Notifier.Information(T("Album was successfully deleted"));
            return Redirect(Url.SliderSummary());
        }

        public ActionResult Item(int sliderId, PagerParameters pagerParameters)
        {
            Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);
            SliderPart sliderPart = _sliderService.Get(sliderId, VersionOptions.Latest).As<SliderPart>();

            if (sliderPart == null)
                return HttpNotFound();

            var sliderItems = _sliderItemService.Get(sliderPart, pager.GetStartIndex(), pager.PageSize, VersionOptions.Latest)
                                      .Select<SliderItemPart, object>(bp => _contentManager.BuildDisplay(bp, "SummaryAdmin"));

            dynamic slider = _services.ContentManager.BuildDisplay(sliderPart, "DetailAdmin");

            var list = Shape.List();
            list.AddRange(sliderItems);
            slider.Content.Add(Shape.Parts_Sliders_Slider_ListAdmin(ContentItems: list), "5");

            var totalItemCount = _sliderItemService.GetCount(sliderPart, VersionOptions.Latest);
            slider.Content.Add(Shape.Pager(pager).TotalItemCount(totalItemCount), "Content:after");

            // Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
            return View((object)slider);
        }




        bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties)
        {
            return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
        }

        void IUpdateModel.AddModelError(string key, LocalizedString errorMessage)
        {
            ModelState.AddModelError(key, errorMessage.ToString());
        }
    }
}